<?php
/**
 * welcome in the world of YACS
 *
 * Well, this script is the front page of a YACS server.
 *
 * If you are looking for general information about YACS, including design principles, please look at [script]help/index.php[/script].
 *
 * Usually the front page is the most often visited page of a web site.
 * Therefore we have crafted it as carefully as possible, to allow for maximum flexibility and efficiency.
 *
 * First of all, YACS offers powerful features to assign content to various areas of the front page.
 * These areas (e.g., cover page, gadget boxes, etc.) are introduced below.
 *
 * Second, YACS offers a large number of customization options,
 * and most parameters that impact the front page can be conveniently changed
 * at the related configuration panel.
 * Look at [script]configure.php[/script] for a full description of these parameters.
 * This configuration panel is accessible from the Control Panel.
 *
 * Also, several extension mechanisms have been added to this page, and we hope that gifted software programmers will take the most out of it.
 * Look at [script]control/scan.php[/script] for more information on YACS hooks and software extensions.
 *
 * And of course, most tags generated by YACS, if not all, make intensive usage of CSS. Therefore the visual rendering can be changed
 * directly by editing the style sheet used in the live skin for the site.
 * Look at [script]scripts/index.php[/script] for more information on skins and templates used by YACS.
 *
 * [title]General structure of a YACS page[/title]
 *
 * Generally speaking the overall YACS page factory handles three different kinds of areas on the screen:
 * - the main panel - This is where most of the text will be placed.
 * Every YACS script is aiming to put some content in the main area.
 * - the extra panel - Extra information, if any, to be displayed on page side.
 * YACS scripts make intensive use of this to further improve site navigation.
 * - the navigation panel - This is common information to be displayed on all pages.
 * Most content of the navigation panel is generated and managed only in the template file of the current skin.
 * However, some script, such as the one that generates the front page, may complement the navigation panel
 * with additional information specific to only one page.
 *
 * Please note that some skins do combine the extra and the navigation panels as a single visual column,
 * where other skins will feature three column, or two columns plus a floating container, etc.
 *
 *
 * [title]The main panel[/title]
 *
 * Several elements compose the main part of this page. From first to last:
 * - Top icons
 * - The cover article
 * - Text produced by hooks included on id 'index.php#prefix'
 * - A dynamic Flash object listing most recent articles
 * - Gadgets boxes
 * - A list of sections. Several layouts are available?
 * - Text produced by hooks included on id 'index.php'
 * - The list of most recent articles. Several layouts are available, as explained below.
 * - The list of most recent files
 * - The list of most recent links
 * - Bottom icons
 * - Text produced by hooks included on id 'index.php#suffix'
 *
 * The cover article is, actually, posted in the section dedicated to global
 * pages. This section is visible from the Site Map.
 * To change the cover page edit it, like you would do for any regular article.
 * You can add images, use various YACS code or any HTML tag to achieve your goal.
 * On completion, publish the article to make it visible at the front page.
 * Rendering of the cover page may be total or partial based on parameter [code]root_cover_at_home[/code].
 * Content of the cover article is formatted through a call to [code]Skin::layout_cover_article()[/code].
 * Though this function has been implemented into [script]skins/skin_skeleton.php[/script],
 * it can be overloaded into [code]skin.php[/code] of any skin if necessary.
 *
 * The prefix hook is used to invoke any software extension bound as follows:
 * - id: 'index.php#prefix'
 * - type: 'include'
 * - parameters: none
 * Use this hook to include any text right after the cover article.
 *
 * The Flash object is a convenient way to dynamically animate the front page, based on most recent articles published.
 * This has to be explicitly activated in the parameter [code]root_flash_at_home[/code].
 *
 * Gadget boxes are used either to display information that is not part of the
 * regular stream of new content, or to specifically focus on special pages.
 * Change parameter [code]root_gadget_boxes_at_home[/code] to disable the display of
 * gadget boxes. Up to 6 gadget boxes can be displayed at the front page.
 *
 * - The most straightforward way to create gadget boxes is to post articles
 * in the section dedicated to gadget boxes. Each article will be put in a
 * separate box.
 *
 * - Moreover, categories can also be configured to list their content in
 * gadget boxes. In this case each category will have its own box,
 * and up to 5 pages and 5 links will be listed per box.
 *
 * - Configure some sections to list their content in gadget boxes. You can
 * select to have either one box per section, with up to 7 pages or links will
 * be listed per box, or to have every article in its own separate box.
 *
 * Activate the display of the Site Map (actually, a downsize version of it) to introduce
 * top-level sections of your site.
 * The layout used by YACS is specified in parameter [code]sections_layout[/code].
 *
 * The main hook is used to invoke any software extension bound as follows:
 * - id: 'index.php'
 * - type: 'include'
 * - parameters: none
 * Use this hook to include any text just before the list of recent publications.
 *
 * By default, articles are formatted through a call to [code]Skin::build_list(... 'decorated')[/code].
 * This function can be overloaded into [code]skin.php[/code] of any skin.
 * The configuration panel for the front page (aka, [script]configure.php[/script]) may be used
 * to adopt another layout depending of your needs.
 * The parameter [code]root_articles_layout[/code] defines the layout to be used at the front page:
 * - [code]daily[/code] - Make titles out of publication dates.
 * This layout is suitable for weblogs. It is the default value. See [script]skins/layout_home_articles_as_daily.php[/script]
 * - [code]newspaper[/code] - Focus on the last published article, and list some articles published previously.
 * This layout is suitable for most sites. See [script]skins/layout_home_articles_as_newspaper.php[/script]
 * - [code]hardboiled[/code] - List the last ten most recent pages.
 * Previous articles may be accessed through sections, or through the index of articles.
 * This layout is suitable for sites providing several different kinds of information. See [script]skins/layout_home_articles_as_hardboiled.php[/script]
 * - [code]slashdot[/code] - List the last ten most recent pages.
 * Previous articles may be accessed through sections, or through the index of articles.
 * This layout is suitable for sites providing several different kinds of information. See [script]skins/layout_home_articles_as_slashdot.php[/script]
 * - [code]decorated[/code] - A compact list of the ten most recent articles.
 * This layout is suitable for sites with a lot of items (gadget boxes, etc.) at the front page. See [script]articles/layout_articles.php[/script]
 * - [code]compact[/code] - A simple list of titles.
 * - [code]alistapart[/code] - Display only the most recent published page.
 * Previous articles may be accessed through a menu.
 * This layout is suitable for small sites with a low activity, maybe with a single section of pages.
 * - [code]no_articles[/code] - Do not mention recent articles.
 * Use this option to fully customize the front page, for example through some hook.
 *
 * The number of articles displayed depends on the selected layout.
 * For example, the alistapart layout displays one single full-page, while slashdot summarizes several articles.
 * To override this number set the parameter [code]root_articles_count_at_home[/code] in the configuration panel for page factory.
 *
 * This front page is also able to display the content of one single section, if its id is specified in the parameter ##root_sections_at_home##.
 * In this case, the list of recent pages may be affected by any overlay that has been activated for the target section.
 * For example, if a section has been overlaid with ##day##, and if its id has been set in ##root_sections_at_home##, then a pretty calendar of coming events will
 * be displayed at the front page.
 *
 * The list of most recent public files can be added as well,
 * by changing explicitly parameter [code]home_with_recent_files[/code].
 *
 * The list of most recent public links can be added as well,
 * by changing explicitly parameter [code]home_with_recent_links[/code].
 *
 * Bottom and trailing icons are clickable images linked to related articles.
 * For example, you would use this to show logos of your partners at the front page,
 * and create one page to introduce each partner.
 * To achieve this, add thumbnails to target pages, then configure the containing section
 * to display them at the front page.
 * Up to 12 images are displayed.
 *
 * The suffix hook is used to invoke any software extension bound as follows:
 * - id: 'index.php#suffix'
 * - type: 'include'
 * - parameters: none
 * Use this hook to include any text at the bottom of the main area, after everything else.
 *
 *
 * [title]The extra panel[/title]
 *
 * Following components are displayed as boxes in the extra panel:
 * - The list of featured articles, if any
 * - News
 * - Articles featured as extra boxes (one box per article) -- see the '[code]extra_boxes[/code]' section
 * - Sections featured as extra boxes (one box per section), if any
 * - Categories configured to appear here, if any - one box per category, with a list of related articles
 * - A list of older pages
 *
 * Featured pages are those articles that have been assigned to the category dedicated to that purpose.
 * To feature one particular article, display it, then use side links to change assigned categories.
 * Select the category named Featured in the drop list and click on the button.
 *
 * [title]The navigation panel[/title]
 * Following items are put in the navigation panel:
 * - The list of most popular pages, if configured in [script]configure.php[/script]
 * - The list of most popular files, if configured in [script]configure.php[/script]
 * - The list of most popular links, if configured in [script]configure.php[/script]
 * - A list of articles selected randomly, if configured in [script]configure.php[/script]
 *
 *
 * [title]Customized templates[/title]
 *
 * You may create a specific template for this page to depart from regular
 * rendering if you wish.
 *
 * YACS looks for specific templates for this page into the skin directory,
 * and it loads:
 * - ##template_home.php## for the regular front page of the server,
 * - or ##template_slash.php## for the topmost page
 *
 * For example, when the server is installed in directory ##/yacs/## the template
 * ##template_home.php## is loaded on url ##/yacs/index.php##, where the template
 * ##template_slash.php## is loaded on url ##/index.php##.
 *
 * When YACS is directly installed at the top level of the server (e.g., when
 * the parameter 'url_to_root' is '/'), only the template ##template_home.php##
 * is used.
 *
 * [title]Meta information[/title]
 *
 * A feeding link has been included, in order to let robots browse this resource when necessary.
 * See [script]feeds/rss.php[/script] for more information.
 *
 * Simlarly, a meta-link to our blogging API is added, to allow for easy
 * auto-discovery of server capability.
 * See [script]services/describe.php[/script] for more information.
 *
 * If geographical information has been set in [script]skins/configure.php[/script], it is included
 * in meta data.
 * See either [link=GeoTags Search Engine]http://geotags.com/[/link]
 * and [link=Free Geocoding Service for 22 Countries]http://www.travelgis.com/geocode/Default.aspx[/link]
 * for more information.
 *
 * @link http://geotags.com/ GeoTags Search Engine
 * @link http://www.travelgis.com/geocode/Default.aspx Free Geocoding Service for 22 Countries
 *
 * Note that, contrary to other regular pages, this one does not trigger the 'tick' hook.
 *
 * @author Bernard Paques
 * @author Christophe Battarel [email]christophe.battarel@altairis.fr[/email]
 * @tester Christian Loubechine
 * @tester Pat
 * @tester Olivier
 * @tester Agnes
 * @tester Guillaume Perez
 * @tester Viviane Zaniroli
 * @tester Anatoly
 * @tester Timster
 * @tester Mordread Wallas
 * @tester Thierry Pinelli (ThierryP)
 * @tester Alain Lesage (Lasares)
 * @reference
 * @license http://www.gnu.org/copyleft/lesser.txt GNU Lesser General Public License
 */

// load global definitions
if($home = getenv('YACS_HOME'))
	include_once str_replace('//', '/', $home.'/').'shared/global.php';
elseif(is_readable('yacs.home') && is_callable('file_get_contents') && ($content = trim(file_get_contents('yacs.home'), " \t\n\r\0\x0B\\/.")) && is_readable($content.'/shared/global.php'))
	include_once $content.'/shared/global.php';
elseif(is_readable('shared/global.php'))
	include_once 'shared/global.php';
elseif(is_readable('yacs/shared/global.php'))
	include_once 'yacs/shared/global.php';
else
	exit('The file shared/global.php has not been found. Please reinstall or mention home directory in file yacs.home or configure the YACS_HOME environment variable.');

// load libraries used in this script
include_once $context['path_to_root'].'feeds/feeds.php'; // some links to newsfeeds
include_once $context['path_to_root'].'links/links.php';

// load localized strings
i18n::bind('root');

// load the skin, and flag topmost page against regular front page
if(($context['script_url'] == '/index.php') && ($context['url_to_root'] != '/'))
	load_skin('slash');
else
	load_skin('home');

// the menu bar may be made of sections
if(isset($context['root_sections_at_home']) && ($context['root_sections_at_home'] != 'none') && isset($context['root_sections_layout']) && ($context['root_sections_layout'] == 'menu')) {

	// default number of sections to list
	if(!isset($context['root_sections_count_at_home']) || ($context['root_sections_count_at_home'] < 1))
		$context['root_sections_count_at_home'] = 5;

	if($items = Sections::list_by_title_for_anchor(NULL, 0, $context['root_sections_count_at_home'], 'menu'))
		$context['page_menu'] = $items;
}

//
// load the cover page
//

// lookup a named page
if($cover_page =& Articles::get('cover'))
	;
elseif($anchor = Sections::lookup('covers'))
	$cover_page =& Articles::get_newest_for_anchor($anchor);

//
// compute page title -- $context['page_title']
//

if(isset($cover_page['title']) && (!isset($context['root_cover_at_home']) || ($context['root_cover_at_home'] == 'full')))
	$context['page_title'] = $cover_page['title'];

// use mobile version
if(!Surfer::is_desktop()) {
	include 'index_on_mobile.php';
	return;
}

//
// compute main panel -- $context['text']
//

// the cover article is not displayed on a mobile device
if((!isset($context['root_cover_at_home']) || ($context['root_cover_at_home'] != 'none'))) {

	// load the cover page --  may be changed in skin.php if necessary
	if(isset($cover_page['id']))
		$context['text'] .= Skin::layout_cover_article($cover_page);

}

// save some database requests
$cache_id = 'index.php#text';
if(!$text =& Cache::get($cache_id)) {

	// the prefix hook
	if(is_callable(array('Hooks', 'include_scripts')))
		$text .= Hooks::include_scripts('index.php#prefix');

	// most recent articles listed in flash, if ming module is available
	if(isset($context['root_flash_at_home']) && ($context['root_flash_at_home'] == 'Y'))
		$text .= Codes::beautify('[news=flash]');

	// gadget boxes, but not on mobiles
	if((!isset($context['root_gadget_boxes_at_home']) || ($context['root_gadget_boxes_at_home'] == 'Y'))) {

		// build an array of boxes
		$gadget_boxes = array();

		// articles to be displayed as gadget boxes
		if($anchors =& Sections::get_anchors_for_anchor(NULL, 'gadget_boxes')) {

			// up to 6 articles to be displayed as gadget boxes
			if($items =& Articles::list_for_anchor_by('publication', $anchors, 0, 6, 'boxes')) {
				foreach($items as $title => $attributes)
					$gadget_boxes[] = array($title, $attributes['content'], $attributes['id']);
			}

		}

		// up to 6 categories to be displayed as gadget boxes
		if($categories = Categories::list_by_date_for_display('home:gadget', 0, 6, 'raw')) {

			// one box per category
			foreach($categories as $id => $attributes) {

				// link to the category page from the box title
				$label =& Skin::build_box_title(Skin::strip($attributes['title']), Categories::get_permalink($attributes), i18n::s('View the category'));

				// articles for this category
				if($items =& Members::list_articles_by_date_for_anchor('category:'.$id, 0, COMPACT_LIST_SIZE+1, 'compact')) {

					// more at the category page
					if(count($items) > COMPACT_LIST_SIZE) {
						@array_splice($items, COMPACT_LIST_SIZE);

						// link to the category page
						$url =& Categories::get_permalink($attributes);
						$items[$url] = i18n::s('More pages').MORE_IMG;
					}

					// one box per category
					$gadget_boxes[] = array($label, Skin::build_list($items, 'compact'), '');

				// else links for this category
				} elseif($items = Links::list_by_date_for_anchor('category:'.$id, 0, COMPACT_LIST_SIZE+1, 'compact')) {

					// limit to five pages only
					if(count($items) > COMPACT_LIST_SIZE) {
						@array_splice($items, COMPACT_LIST_SIZE);

						// link to the category page
						$url =& Categories::get_permalink($attributes);
						$items[$url] = i18n::s('More links').MORE_IMG;
					}

					$gadget_boxes[] = array($label, Skin::build_list($items, 'compact'), '');

				}
			}
		}

		// sections to be displayed as gadget boxes
		if($anchors =& Sections::get_anchors_for_anchor(NULL, 'gadget')) {

			// one box per section
			foreach($anchors as $anchor) {
				$box = array();

				// sanity check
				if(!$section =& Anchors::get($anchor))
					continue;

				// link to the section page from box title
				$box['title'] =& Skin::build_box_title($section->get_title(), $section->get_url(), i18n::s('View the section'));

				// build a compact list
				$box['list'] = array();

				// add matching sections, if any
				if($items = Sections::list_by_title_for_anchor($anchor, 0, COMPACT_LIST_SIZE+1 - count($box['list']), 'compact'))
					$box['list'] = array_merge($box['list'], $items);

				// add matching articles
				if((COMPACT_LIST_SIZE >= count($box['list'])) && ($items =& Articles::list_for_anchor_by('publication', $anchor, 0, COMPACT_LIST_SIZE+1 - count($box['list']), 'compact')))
					$box['list'] = array_merge($box['list'], $items);

				// add matching links, if any
				if((COMPACT_LIST_SIZE >= count($box['list'])) && ($items = Links::list_by_date_for_anchor($anchor, 0, COMPACT_LIST_SIZE+1 - count($box['list']), 'compact')))
					$box['list'] = array_merge($box['list'], $items);

				// more at the section page
				if(count($box['list']) > COMPACT_LIST_SIZE) {
					@array_splice($box['list'], COMPACT_LIST_SIZE);

					// link to the section page
					$box['list'] = array_merge($box['list'], array($section->get_url() => i18n::s('More pages').MORE_IMG));
				}

				// render the html for the box
				if(count($box['list']))
					$box['text'] =& Skin::build_list($box['list'], 'compact');

				// give a chance to associates to populate empty sections
				elseif(Surfer::is_associate())
					$box['text'] = Skin::build_link($section->get_url(), i18n::s('View the section'), 'shortcut');

				// append a box
				if(isset($box['text']) && $box['text'])
					$gadget_boxes[] = array($box['title'], $box['text'], $section->get_nick_name());

			}
		}

		// we do have some boxes to display
		if(count($gadget_boxes)) {

			// limit the number of boxes displayed
			@array_splice($gadget_boxes, 6);

			// gadget box rendering
			$text .= "\n".'<p id="gadgets_prefix"> </p>'."\n";
			foreach($gadget_boxes as $gadget_box)
				$text .= Skin::build_box($gadget_box[0], $gadget_box[1], 'gadget', isset($gadget_box[2])?$gadget_box[2]:NULL);
			$text .= '<p id="gadgets_suffix"> </p>'."\n";
		}

	}

	// show content of only one section
	$target_section = NULL;
	if(isset($context['root_sections_at_home']) && ((int)$context['root_sections_at_home'] > 0)) {

		// get the item from the database --do not cast to int, because of following UTF-8 to unicode conversion
		$target_section =& Sections::get($context['root_sections_at_home']);

	}

	// display sections as a freemind map
	if(isset($context['root_sections_at_home']) && ($context['root_sections_at_home'] != 'none') && isset($context['root_sections_layout']) && ($context['root_sections_layout'] == 'freemind'))
		$text .= Codes::render_freemind('sections');

	// sections at the front page
	elseif(isset($context['root_sections_at_home']) && ($context['root_sections_at_home'] != 'none')) {

		// load the layout to use
		switch($context['root_sections_layout']) {
		case 'decorated':
			include_once $context['path_to_root'].'sections/layout_sections.php';
			$layout = new Layout_sections();
			break;
		case 'map':
			include_once $context['path_to_root'].'sections/layout_sections_as_yahoo.php';
			$layout = new Layout_sections_as_yahoo();
			$layout->set_variant(20); // show more elements at the front page
			break;
		default:

			// load layout, if one exists
			if(is_readable($context['path_to_root'].'sections/layout_sections_as_'.$context['root_sections_layout'].'.php')) {
				$name = 'layout_sections_as_'.$context['root_sections_layout'];
				include_once $context['path_to_root'].'sections/'.$name.'.php';
				$layout = new $name;

			// no layout to use
			} else {

				// useful warning for associates
				if(Surfer::is_associate())
					Logger::error(sprintf(i18n::s('Warning: No script exists for the customized layout %s'), $context['root_sections_layout']));

				// load default layout
				include_once $context['path_to_root'].'sections/layout_sections_as_yahoo.php';
				$layout = new Layout_sections_as_yahoo();
			}
		}

		// the maximum number of sections
		if(is_object($layout))
			$items_per_page = $layout->items_per_page();
		else
			$items_per_page = SECTIONS_PER_PAGE;

		// list top sections
		$anchor = NULL;

		// look at only one section
		if(isset($target_section['id']))
			$anchor = 'section:'.$target_section['id'];

		// query the database and layout that stuff
		$items = '';
		if($context['root_sections_layout'] != 'menu')
			$items = Sections::list_by_title_for_anchor($anchor, 0, $items_per_page, $layout);

		// we have an array to format
		if(is_array($items)) {

			// two columns
			if($context['root_sections_layout'] == 'map')
				$items =& Skin::build_list($items, '2-columns');

			// decorated
			else
				$items =& Skin::build_list($items, 'decorated');
		}

		// make a box
		if($items)
			$text .= $items;

	}

	// the main hook
	if(is_callable(array('Hooks', 'include_scripts')))
		$text .= Hooks::include_scripts('index.php');

	// the list of most recent articles
	switch($context['root_articles_layout']) {
	case 'compact':
		include_once $context['path_to_root'].'articles/layout_articles_as_compact.php';
		$layout = new Layout_articles_as_compact();
		break;
	case 'decorated':
		include_once $context['path_to_root'].'articles/layout_articles.php';
		$layout = new Layout_articles();
		break;
	case 'no_articles':
		$layout = NULL;
		break;
	default:

		// load layout, if one exists, for the home page
		if(is_readable($context['path_to_root'].'skins/layout_home_articles_as_'.$context['root_articles_layout'].'.php')) {
			$name = 'layout_home_articles_as_'.$context['root_articles_layout'];
			include_once $context['path_to_root'].'skins/'.$name.'.php';
			$layout = new $name;

		// no layout to use
		} else {

			// useful warning for associates
			if(Surfer::is_associate())
				Logger::error(sprintf(i18n::s('Warning: No script exists for the customized layout %s'), $context['root_articles_layout']));

			// load default layout
			include_once $context['path_to_root'].'skins/layout_home_articles_as_daily.php';
			$layout = new Layout_home_articles_as_daily();
		}
	}

	// the maximum number of articles
	if(isset($context['root_articles_count_at_home']) && ($context['root_articles_count_at_home'] > 0))
		$items_per_page = $context['root_articles_count_at_home'];
	elseif(is_object($layout))
		$items_per_page = $layout->items_per_page();
	else
		$items_per_page = ARTICLES_PER_PAGE;

	// look for articles in only one section
	if(isset($target_section['id'])) {

		// get the overlay for content of this section, if any
		$content_overlay = NULL;
		if(isset($target_section['content_overlay'])) {
			include_once $context['path_to_root'].'overlays/overlay.php';
			$content_overlay = Overlay::bind($target_section['content_overlay']);
		}

		// delegate rendering to the overlay, where applicable
		if(is_object($content_overlay) && ($overlaid = $content_overlay->render('articles', 'section:'.$target_section['id']))) {
			$text .= $overlaid;
			$items = '';

		// else use the regular layout
		} else
			$items =& Articles::list_for_anchor('section:'.(int)$context['root_sections_at_home'], 0, $items_per_page, $layout);

	// no layout
	} elseif($layout === NULL)
		$items = '';

	// look for recent articles across all sections
	elseif(!$items =& Articles::list_(0, $items_per_page, $layout)) {

		// no article yet
		$items = '<p>'.i18n::s('No page to display.');
		if(Surfer::is_associate())
			$items .= ' '.sprintf(i18n::s('Use the %s to populate this server.'), Skin::build_link('help/populate.php', i18n::s('Content Assistant'), 'shortcut'));
		$items .= '</p>';

	}

	// we have an array to format
	if(is_array($items)) {

		// add a link to articles index
		$items['articles/'] = array('', i18n::s('All pages'), '', 'shortcut');

		// make a string out of the array
		if(isset($context['root_articles_layout']) && ($context['root_articles_layout'] == 'compact'))
			$items =& Skin::build_list($items, 'compact');
		else
			$items =& Skin::build_list($items, 'decorated');

		// add a title in case of complex page
		$title = '';
		if(preg_match('/<h2>|<h3>/', $context['text'].$text)) {
			$title = i18n::s('Recent Pages');
		}

		// make a box
		if($items)
			$items =& Skin::build_box($title, $items, 'header1', 'recent_articles');

	}
	$text .= $items;

	// list recent files, except on mobiles
	if(isset($context['home_with_recent_files']) && ($context['home_with_recent_files'] == 'Y')){

		// box title
		$title = i18n::s('Recent files');

		// link to the index page from the box title
		$title =& Skin::build_box_title($title, 'files/', i18n::s('Files'));

		// list most recent files
		if($items = Files::list_by_date(0, COMPACT_LIST_SIZE, 'dates'))
			$text .= Skin::build_box($title, Skin::build_list($items, 'compact'), 'header1', 'recent_files');

	}

	// list recent links, except on mobiles
	if(isset($context['home_with_recent_links']) && ($context['home_with_recent_links'] == 'Y')){

		// box title
		$title = i18n::s('Recent links');

		// link to the index page from the box title
		$title =& Skin::build_box_title($title, 'links/', i18n::s('More links'));

		// list most recent links
		if($items = Links::list_by_date(0, COMPACT_LIST_SIZE, 'dates'))
			$text .= Skin::build_box($title, Skin::build_list($items, 'compact'), 'header1', 'recent_links');

	}

	// the suffix hook
	if(is_callable(array('Hooks', 'include_scripts')))
		$text .= Hooks::include_scripts('index.php#suffix');

	// save in cache, whatever change, for 1 minute
	Cache::put($cache_id, $text, 'stable', 60);
}

// page content
$context['text'] .= $text;

// the cover article is not displayed on a mobile device
if((!isset($context['root_cover_at_home']) || ($context['root_cover_at_home'] != 'none'))) {

	// may be changed in skin.php if necessary
	if(isset($cover_page['trailer']))
		$context['text'] .= Codes::beautify($cover_page['trailer']);

}

//
// compute extra information -- $context['extra']
//

// page tools
//
if(Surfer::is_associate()) {
	$context['page_tools'][] = Skin::build_link('configure.php', i18n::s('Configure'));
	if(isset($cover_page['id']))
		$context['page_tools'][] = Skin::build_link(Articles::get_permalink($cover_page), i18n::s('Cover page'), 'basic');
	if(($section = Sections::get('gadget_boxes')) && isset($section['id']))
		$context['page_tools'][] = Skin::build_link(Sections::get_permalink($section), i18n::s('Gadget boxes'), 'basic');
	if(($section = Sections::get('extra_boxes')) && isset($section['id']))
		$context['page_tools'][] = Skin::build_link(Sections::get_permalink($section), i18n::s('Extra boxes'), 'basic');
	if(($section = Sections::get('navigation_boxes')) && isset($section['id']))
		$context['page_tools'][] = Skin::build_link(Sections::get_permalink($section['id']), i18n::s('Navigation boxes'), 'basic');
}

// save some database requests
$cache_id = 'index.php#extra_news';
if(!$text =& Cache::get($cache_id)) {

	// show featured articles -- set in configure.php
	if(isset($context['root_featured_layout']) && ($context['root_featured_layout'] != 'none')) {

		// set in configure.php
		if(!isset($context['root_featured_count']) || ($context['root_featured_count'] < 1))
			$context['root_featured_count'] = 7;

		// the category used to assign featured pages
		$anchor =& Categories::get(i18n::c('featured'));
		if($anchor['id'] && ($items =& Members::list_articles_by_date_for_anchor('category:'.$anchor['id'], 0, ($context['root_featured_count']+1), 'news'))) {

			// link to the category page from the box title
			$title =& Skin::build_box_title($anchor['title'], Categories::get_permalink($anchor), i18n::s('Featured pages'));

			// limit to seven links only
			if(@count($items) > $context['root_featured_count']) {
				@array_splice($items, $context['root_featured_count']);

				// link to the category page
				$url = Categories::get_permalink($anchor);
				$items[$url] = i18n::s('Featured pages').MORE_IMG;

			}

			// render html
			if(is_array($items))
				$items =& Skin::build_list($items, 'news');

			// we do have something to display
			if($items) {

				// animate the text if required to do so
				if($context['root_featured_layout'] == 'scroll') {
					$items = Skin::scroll($items);
					$box_id = 'scrolling_featured';
				} elseif($context['root_featured_layout'] == 'rotate') {
					$items = Skin::rotate($items);
					$box_id = 'rotating_featured';
				} else
					$box_id = 'featured';

				// make an extra box -- the css id is either #featured, #scrolling_featured or #rotating_featured
				$text .= Skin::build_box($title, $items, 'news', $box_id);
			}
		}
	}

	// show news -- set in configure.php
	if(isset($context['root_news_layout']) && ($context['root_news_layout'] != 'none')) {

		// list news from sections where home_map == 'news'
		if($anchors =& Sections::get_anchors_for_anchor(NULL, 'news')) {

			// build a complete box
			$box['bar'] = array();
			$box['text'] = '';

			// set in configure.php
			if(!isset($context['root_news_count']) || ($context['root_news_count'] < 1))
				$context['root_news_count'] = 7;

			// list articles by date
			$items =& Articles::list_for_anchor_by('publication', $anchors, 0, $context['root_news_count'], 'news');

			// render html
			if(is_array($items))
				$box['text'] .= Skin::build_list($items, 'news');
			elseif(is_string($items))
				$box['text'] .= $items;

			// we do have something to display
			if($box['text']) {

				// animate the text if required to do so
				if($context['root_news_layout'] == 'scroll') {
					$box['text'] = Skin::scroll($box['text']);
					$box['id'] = 'scrolling_news';
				} elseif($context['root_news_layout'] == 'rotate') {
					$box['text'] = Skin::rotate($box['text']);
					$box['id'] = 'rotating_news';
				} else
					$box['id'] = 'news';

				// make an extra box -- the css id is either #news, #scrolling_news or #rotating_news
				$text .= Skin::build_box(i18n::s('News'), $box['text'], 'news', $box['id']);
			}
		}
	}

	// save in cache, whatever change, for 5 minutes
	Cache::put($cache_id, $text, 'stable', 300);
}

// news
$context['components']['news'] = $text;

// save some database requests
$cache_id = 'index.php#extra';
if(!$text =& Cache::get($cache_id)) {

	// list extra boxes
	if($anchors =& Sections::get_anchors_for_anchor(NULL, 'extra_boxes')) {

		// the maximum number of boxes is a global parameter
		if(!isset($context['site_extra_maximum']) || !$context['site_extra_maximum'])
			$context['site_extra_maximum'] = 7;

		// articles to be displayed as extra boxes
		if($items =& Articles::list_for_anchor_by('publication', $anchors, 0, $context['site_extra_maximum'], 'boxes')) {
			foreach($items as $title => $attributes)
				$text .= Skin::build_box($title, $attributes['content'], 'boxes', $attributes['id'])."\n";
		}

	}

	// one extra box per section, from sub-sections
	if($anchors =& Sections::get_anchors_for_anchor(NULL, 'extra')) {

		// one box per section
		foreach($anchors as $anchor) {
			$box = array();

			// sanity check
			if(!$section =& Anchors::get($anchor))
				continue;

			// link to the section page from box title
			$box['title'] =& Skin::build_box_title($section->get_title(), $section->get_url(), i18n::s('View the section'));

			// build a compact list
			$box['list'] = array();

			// list matching sections, if any
			if($items = Sections::list_by_title_for_anchor($anchor, 0, COMPACT_LIST_SIZE+1 - count($box['list']), 'compact'))
				$box['list'] = array_merge($box['list'], $items);

			// add matching articles
			if(COMPACT_LIST_SIZE >= count($box['list'])) {

				// use ordering options set for the section
				if($section->has_option('articles_by_title'))
					$items =& Articles::list_for_anchor_by('title', $anchor, 0, COMPACT_LIST_SIZE+1 - count($box['list']), 'compact');
				elseif($section->has_option('articles_by_publication'))
					$items =& Articles::list_for_anchor_by('publication', $anchor, 0, COMPACT_LIST_SIZE+1 - count($box['list']), 'compact');
				elseif($section->has_option('articles_by_rating'))
					$items =& Articles::list_for_anchor_by('rating', $anchor, 0, COMPACT_LIST_SIZE+1 - count($box['list']), 'compact');
				else
					$items =& Articles::list_for_anchor($anchor, 0, COMPACT_LIST_SIZE+1 - count($box['list']), 'compact');

				if($items)
					$box['list'] = array_merge($box['list'], $items);

			}

			// add matching links, if any
			if((COMPACT_LIST_SIZE >= count($box['list'])) && ($items = Links::list_by_date_for_anchor($anchor, 0, COMPACT_LIST_SIZE+1 - count($box['list']), 'compact')))
				$box['list'] = array_merge($box['list'], $items);

			// more at the section page
			if(count($box['list']) > COMPACT_LIST_SIZE) {
				@array_splice($box['list'], COMPACT_LIST_SIZE);

				// link to the section page
				$box['list'] = array_merge($box['list'], array($section->get_url() => i18n::s('More pages').MORE_IMG));
			}

			// render the html for the box
			$box['text'] = '';
			if(count($box['list']))
				$box['text'] =& Skin::build_list($box['list'], 'compact');

			// give a chance to associates to populate empty sections
			elseif(Surfer::is_associate())
				$box['text'] = Skin::build_link($section->get_url(), i18n::s('View the section'), 'shortcut');

			// append a box
			if($box['text'])
				$text .= Skin::build_box($box['title'], $box['text'], 'boxes');

		}
	}

	// list categories to display among extra boxes
	if($categories = Categories::list_by_date_for_display('home:extra', 0, 7, 'raw')) {

		// one box per category
		foreach($categories as $id => $attributes) {

			// link to the category page from the box title
			$label =& Skin::build_box_title(Skin::strip($attributes['title']), Categories::get_permalink($attributes), i18n::s('View the category'));

			// build a compact list
			$box['list'] = array();

			// list matching categories, if any
			if($items = Categories::list_by_title_for_anchor('category:'.$id, 0, COMPACT_LIST_SIZE+1 - count($box['list']), 'compact'))
				$box['list'] = array_merge($box['list'], $items);

			// add matching articles, if any
			if((COMPACT_LIST_SIZE >= count($box['list'])) && ($items =& Members::list_articles_by_date_for_anchor('category:'.$id, 0, COMPACT_LIST_SIZE+1 - count($box['list']), 'compact')))
				$box['list'] = array_merge($box['list'], $items);

			// add matching links, if any
			if((COMPACT_LIST_SIZE >= count($box['list'])) && ($items = Links::list_by_date_for_anchor('category:'.$id, 0, COMPACT_LIST_SIZE+1 - count($box['list']), 'compact')))
				$box['list'] = array_merge($box['list'], $items);

			// more at the category page
			if(count($box['list']) > COMPACT_LIST_SIZE) {
				@array_splice($box['list'], COMPACT_LIST_SIZE);

				// link to the category page
				$box['list'] = array_merge($box['list'], array(Categories::get_permalink($attributes) => i18n::s('More pages').MORE_IMG));
			}

			$text .= Skin::build_box($label, Skin::build_list($box['list'], 'compact'), 'boxes')."\n";

		}
	}

	// show last poll, if any
	if(isset($context['home_with_recent_poll']) && ($context['home_with_recent_poll'] == 'Y')) {

		$anchor =& Anchors::get('section:polls');
		if(is_object($anchor) && ($item =& Articles::get_newest_for_anchor($anchor->get_reference()))) {

			// build a box
			$box = array();
			$box['text'] = '';

			// get a title
			$box['title'] = Codes::beautify_title($item['title']);

			// link to the index page for polls
			$box['title'] =& Skin::build_box_title($box['title'], $anchor->get_url(), i18n::s('Polls'));

			// the introductory text
			if($item['introduction'])
				$box['text'] .= Codes::beautify($item['introduction']);

			// get the related overlay, if any
			$overlay = NULL;
			include_once $context['path_to_root'].'overlays/overlay.php';
			if(isset($item['overlay']))
				$overlay = Overlay::load($item);

			// insert overlay data, if any
			if(is_object($overlay))
				$box['text'] .= $overlay->get_text('box', $item);

			if($content)
				$text .= Skin::build_box($box['title'], $box['text'], 'boxes', 'extra_poll');
		}
	}

	// list recent pages
	if(isset($context['home_with_older_articles']) && ($context['home_with_older_articles'] == 'Y')) {

		if($items =& Articles::list_by('publication', $items_per_page, COMPACT_LIST_SIZE+1, 'compact')) {

			// more at the index page
			if(count($items) > COMPACT_LIST_SIZE) {
				@array_splice($items, COMPACT_LIST_SIZE);

				$items['articles/'] = i18n::s('All pages').MORE_IMG;
			}

			$text .= Skin::build_box(i18n::s('Recent Pages'), Skin::build_list($items, 'compact'), 'boxes');
		}
	}

	// save in cache, whatever change, for 5 minutes
	Cache::put($cache_id, $text, 'stable', 300);
}

// page extra content
$context['components']['boxes'] = $text;

// referrals, if any
if(Surfer::is_associate() || (isset($context['with_referrals']) && ($context['with_referrals'] == 'Y')))
	$context['components']['referrals'] =& Skin::build_referrals('index.php');

//
// compute navigation information -- $context['navigation']
//

// save some database requests
$cache_id = 'index.php#navigation';
if(!$text =& Cache::get($cache_id)) {

	// list most recent peering servers
	if(isset($context['home_with_peering_servers']) && ($context['home_with_peering_servers'] == 'Y')) {
		include_once $context['path_to_root'].'servers/servers.php';
		if($items = Servers::list_by_date(0, COMPACT_LIST_SIZE, 'compact'))
			$text .= Skin::build_box(i18n::s('Peers'), Skin::build_list($items, 'compact'), 'navigation', 'recent_servers');
	}

	// list most popular articles
	if(isset($context['home_with_top_articles']) && ($context['home_with_top_articles'] == 'Y')) {
		if($items =& Articles::list_by('hits', 0, COMPACT_LIST_SIZE, 'compact'))
			$text .= Skin::build_box(i18n::s('Popular Pages'), Skin::build_list($items, 'compact'), 'navigation', 'popular_articles');
	}

	// list most popular files
	if(isset($context['home_with_top_files']) && ($context['home_with_top_files'] == 'Y')) {
		if($items = Files::list_by_hits(0, COMPACT_LIST_SIZE, 'compact'))
			$text .= Skin::build_box(i18n::s('Popular Files'), Skin::build_list($items, 'compact'), 'navigation', 'popular_files');
	}

	// list most popular links
	if(isset($context['home_with_top_links']) && ($context['home_with_top_links'] == 'Y')) {
		include_once $context['path_to_root'].'links/links.php';
		if($items = Links::list_by_hits(0, COMPACT_LIST_SIZE, 'compact'))
			$text .= Skin::build_box(i18n::s('Popular Links'), Skin::build_list($items, 'compact'), 'navigation', 'popular_links');
	}

	// list random articles
	if(isset($context['home_with_random_articles']) && ($context['home_with_random_articles'] == 'Y')) {
		if($items =& Articles::list_by('random', 0, COMPACT_LIST_SIZE, 'compact'))
			$text .= Skin::build_box(i18n::s('Random Pages'), Skin::build_list($items, 'compact'), 'navigation', 'random_articles');
	}

	// save in cache, whatever change, for 5 minutes
	Cache::put($cache_id, $text, 'stable', 300);
}

// page navigation content
$context['navigation'] .= $text;

// a meta link to a feeding page
$context['page_header'] .= "\n".'<link rel="alternate" href="'.$context['url_to_root'].Feeds::get_url('rss').'" title="RSS" type="application/rss+xml" />';

// render the skin
render_skin();

?>